package cn.deschen.search.index;

import cn.deschen.common.utils.SpringUtil;
import cn.deschen.search.constants.OpType;
import cn.deschen.search.index.adCreative.AdCreativeIndex;
import cn.deschen.search.index.adCreative.AdCreativeObject;
import cn.deschen.search.index.adKeyword.AdKeywordIndex;
import cn.deschen.search.index.adKeyword.AdKeywordObject;
import cn.deschen.search.index.adPlan.AdPlanIndex;
import cn.deschen.search.index.adPlan.AdPlanObject;
import cn.deschen.search.index.adRegion.AdRegionIndex;
import cn.deschen.search.index.adRegion.AdRegionObject;
import cn.deschen.search.index.adTag.AdTagIndex;
import cn.deschen.search.index.adTag.AdTagObject;
import cn.deschen.search.index.adUnit.AdUnitIndex;
import cn.deschen.search.index.adUnit.AdUnitObject;
import cn.deschen.search.index.adUnitEle.AdUnitEleIndex;
import cn.deschen.search.index.adUnitEle.AdUnitEleObject;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author hanbin_chen
 * @Description 索引处理器，用于保存、更新、删除索引
 * @DateTime 2021/6/8
 * @Version V1.0.0
 */
@Slf4j
public class IndexHandler {

    /**
     * 处理二级索引
     *
     * @param plan 推广计划
     * @param type 操作类型
     */
    public static void handlerLevel2Index(AdPlanObject plan, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdPlanIndex.class),
                plan.getId(),
                plan,
                type);
    }

    /**
     * 处理二级索引
     *
     * @param creative 创意广告
     * @param type     操作类型
     */
    public static void handlerLevel2Index(AdCreativeObject creative, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdCreativeIndex.class),
                creative.getId(),
                creative,
                type);
    }

    /**
     * 处理二级索引
     *
     * @param tag  兴趣标签
     * @param type 操作类型
     */
    public static void handlerLevel2Index(AdTagObject tag, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdTagIndex.class),
                tag.getId(),
                tag,
                type);
    }

    /**
     * 处理二级索引
     *
     * @param keyword 关键词
     * @param type    操作类型
     */
    public static void handlerLevel2Index(AdKeywordObject keyword, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdKeywordIndex.class),
                keyword.getId(),
                keyword,
                type);
    }

    /**
     * 处理二级索引
     *
     * @param region 地区
     * @param type   操作类型
     */
    public static void handlerLevel2Index(AdRegionObject region, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdRegionIndex.class),
                region.getId(),
                region,
                type);
    }


    /**
     * 处理三级索引
     *
     * @param unit 推广单元
     * @param type 操作类型
     */
    public static void handlerLevel3Index(AdUnitObject unit, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdUnitIndex.class),
                unit.getId(),
                unit,
                type);
    }


    /**
     * 处理四级索引
     *
     * @param unitEle 推广单元-元素
     * @param type       操作类型
     */
    public static void handlerLevel4Index(AdUnitEleObject unitEle, OpType type) {
        handleBinlogEvent(SpringUtil.getBean(AdUnitEleIndex.class),
                AdUnitEleIndex.generateKey(unitEle),
                unitEle,
                type);
    }

    /**
     * 根据不同数据库操作类型，对索引进行处理
     *
     * @param indexAware 索引接口
     * @param key        键
     * @param value      值，保存的叔据
     * @param type       操作类型
     */
    public static <K, V extends IndexObject> void handleBinlogEvent(IndexAware<K, V> indexAware,
                                                                    K key,
                                                                    V value,
                                                                    OpType type) {
        switch (type) {
            case ADD: {
                if (value.isDeleted()) {
                    indexAware.delete(key);
                } else {
                    indexAware.add(key, value);
                }
            }
            break;
            case UPDATE: {
                if (value.isDeleted()) {
                    indexAware.delete(key);
                } else {
                    indexAware.update(key, value);
                }
            }
            break;
            case DELETE:
                indexAware.delete(key);
                break;
            case OTHER:
                log.error("操作类型不存在\n indexAware:{}\n type={}", indexAware, type);
                break;
        }
    }
}
